<template>
  <div class="app-container">
    <el-form
      class="searchform"
      :model="queryParams"
      ref="queryForm"
      size="small"
      label-width="100px"
    >
      <el-row>
        <el-col :span="5">
          <el-form-item label="所属部门" prop="deptId">
            <treeselect
              v-model="queryParams.deptId"
              style="width: 100%"
              :options="deptOptions"
              :show-count="true"
              placeholder="请选择"
            />
          </el-form-item>
        </el-col>
        <el-col :span="5">
          <el-form-item label="职务">
            <el-input
              v-model="queryParams.duties"
              placeholder="请输入"
              clearable
              @keyup.enter.native="handleQuery"
            />
          </el-form-item>
        </el-col>
        <el-col :span="5">
          <el-form-item label="用户名称" prop="userName">
            <el-input
              v-model="queryParams.userName"
              placeholder="请输入用户名称"
              clearable
              @keyup.enter.native="handleQuery"
            />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="5">
          <el-form-item label="手机号码" prop="phonenumber">
            <el-input
              v-model="queryParams.phonenumber"
              placeholder="请输入"
              clearable
              @keyup.enter.native="handleQuery"
            />
          </el-form-item>
        </el-col>
        <el-col :span="5">
          <el-form-item label="状态" prop="status">
            <el-select
              v-model="queryParams.status"
              placeholder="用户状态"
              clearable
              style="width: 100%"
            >
              <el-option
                v-for="dict in dict.type.sys_normal_disable"
                :key="dict.value"
                :label="dict.label"
                :value="dict.value"
              />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="5">
          <el-form-item label="创建时间">
            <el-date-picker
              v-model="dateRange"
              value-format="yyyy-MM-dd HH:mm:ss"
              type="daterange"
              style="width: 100%"
              range-separator="-"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              :default-time="['00:00:00', '23:59:59']"
            ></el-date-picker>
          </el-form-item>
        </el-col>
        <el-col :span="5">
          <el-form-item label-width="20px">
            <el-button
              type="primary"
              icon="el-icon-search"
              size="mini"
              @click="handleQuery"
              >搜索</el-button
            >
            <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
              >重置</el-button
            >
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>

    <div class="table-wrapper">
      <div class="tableoperation">
        <el-row :gutter="10" class="mb8">
          <el-col :span="1.5">
            <el-button
              type="primary"
              plain
              icon="el-icon-plus"
              size="mini"
              @click="handleAdd"
              v-hasPermi="['system:user:add']"
              >新增</el-button
            >
          </el-col>
          <el-col :span="1.5">
            <el-button
              type="info"
              plain
              icon="el-icon-upload2"
              size="mini"
              @click="handleImport"
              v-hasPermi="['system:user:import']"
              >导入</el-button
            >
          </el-col>
          <el-col :span="1.5">
            <el-button
              type="warning"
              plain
              icon="el-icon-download"
              size="mini"
              @click="handleExport"
              v-hasPermi="['system:user:export']"
              >导出</el-button
            >
          </el-col>
          <el-col :span="1.5">
            <el-button
              type="primary"
              plain
              icon="el-icon-upload"
              size="mini"
              :disabled="selection.length != 1"
              @click="openCer()"
              >上传证书</el-button
            >
          </el-col>
          <el-col :span="1.5" class="certificate">
            <el-button
              type="primary"
              plain
              icon="el-icon-upload"
              size="mini"
              :disabled="selection.length != 1"
              @click="openUkeyDialog"
              >绑定ukey</el-button
            >
          </el-col>
        </el-row>
      </div>

      <el-table
        v-loading="loading"
        :height="height - 443 + 'px'"
        :data="userList"
        @selection-change="handleSelectionChange"
        @row-dblclick="(row) => handleUpdate(row, '3')"
      >
        <el-table-column type="selection" width="50" align="center" />
        <el-table-column type="index" label="序号" width="50" align="center" >
          <template slot-scope="scope">
            <div style="text-align: center;">{{ scope.$index + 1 }}</div>
          </template>
        </el-table-column>
        <el-table-column
          label="账户"
          align="center"
          key="userName"
          prop="userName"
          :show-overflow-tooltip="true"
          width="100"
        />
        <el-table-column
          label="姓名"
          align="center"
          key="nickName"
          prop="nickName"
          :show-overflow-tooltip="true"
          width="100"
        />
        <el-table-column
          label="性别"
          align="center"
          :show-overflow-tooltip="true"
          width="50"
        >
          <template slot-scope="scope">
            <dict-tag
              :options="dict.type.sys_user_sex"
              :value="scope.row.sex"
            />
          </template>
        </el-table-column>
        <el-table-column
          label="部门"
          align="center"
          key="deptName"
          prop="dept.deptName"
          v-if="columns[3].visible"
          :show-overflow-tooltip="true"
        />
        <el-table-column
          label="职务"
          align="center"
          prop="duties"
          :show-overflow-tooltip="true"
        />
        <el-table-column
          label="身份证号"
          align="center"
          prop="idCard"
          :show-overflow-tooltip="true"
        />
        <el-table-column
          label="手机"
          align="center"
          key="phonenumber"
          prop="phonenumber"
          v-if="columns[4].visible"
          width="120"
        />
        <el-table-column
          label="状态"
          align="center"
          :show-overflow-tooltip="true"
          width="100"
        >
          <template slot-scope="scope">
            <dict-tag
              :options="dict.type.sys_normal_disable"
              :value="scope.row.status"
            />
          </template>
        </el-table-column>
        <el-table-column
          label="查看证书"
          align="center"
          width="120"
          class-name="small-padding fixed-width"
        >
          <template slot-scope="scope">
            <el-button
              size="mini"
              type="primary"
              plain
              class="mybutton"
              @click="openCerList(scope.row)"
              v-if="scope.row.calibrationCount"
              >证书({{ scope.row.calibrationCount }})本</el-button
            >
            <el-button v-else type="info" class="mybutton" plain disabled
              >无证书</el-button
            >
          </template>
        </el-table-column>
        <el-table-column label="签章图片" align="center">
          <template slot-scope="{ row }">
            <!-- <el-popover
						placement="top-start"
						title=""
						width="200"
						trigger="hover"
						>
						<div class="seal">
							<img :src="row.sealurl">
						</div> -->
            <div class="seal" slot="reference">
              <img :src="row.sealurl" />
            </div>
            <!-- </el-popover> -->
          </template>
        </el-table-column>

        <el-table-column
          label="操作"
          width="250"
          align="center"
          class-name="small-padding fixed-width"
        >
          <template slot-scope="scope">
            <div v-if="scope.row.userId !== 1">
              <el-button
                type="text"
                @click="handleUpdate(scope.row, '2')"
                v-hasPermi="['system:user:edit']"
                >编辑</el-button
              >
              <el-button
                type="text"
                style="color: #f32d2d"
                @click="handleDelete(scope.row)"
                v-hasPermi="['system:user:remove']"
                >删除</el-button
              >
              <el-button
                type="text"
                @click="handleResetPwd(scope.row)"
                v-hasPermi="['system:user:resetPwd']"
                >重置密码</el-button
              >

              <el-dropdown
                size="mini"
                @command="(command) => handleCommand(command, scope.row)"
                trigger="click"
              >
                <el-button size="mini" type="text" icon="el-icon-d-arrow-right"
                  >更多</el-button
                >
                <el-dropdown-menu slot="dropdown">
                  <el-dropdown-item
                    command="handleSysSeal"
                    icon="el-icon-s-check"
                    >生成签章</el-dropdown-item
                  >
                  <el-dropdown-item command="handleHanSeal" icon="el-icon-edit"
                    >手写签名</el-dropdown-item
                  >
                </el-dropdown-menu>
              </el-dropdown>
            </div>

            <el-button v-else type="text" style="color: #fff; width: 0">
              ' '
            </el-button>
          </template>
        </el-table-column>
      </el-table>

      <pagination
        v-show="total > 0"
        :total="total"
        :page.sync="queryParams.pageNum"
        :limit.sync="queryParams.pageSize"
        @pagination="getList"
      />
    </div>

    <!-- 证书弹框 -->
    <el-dialog
      :title="status == '1' ? '添加证书' : '修改证书'"
      :visible.sync="cerVisible"
      width="1000px"
      append-to-body
      v-dialogDrag="true"
    >
      <el-form
        ref="cerForm"
        class="cerForm"
        :model="cerForm"
        :rules="addCerRules"
        size="small"
        label-width="100px"
      >
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="姓名" prop="userName">
              <el-input v-model="cerForm.userName" disabled />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="性别" prop="sex">
              <el-select v-model="cerForm.sex" disabled>
                <el-option
                  v-for="dict in dict.type.sys_user_sex"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="身份证号" prop="idCard">
              <el-input v-model="cerForm.idCard" disabled />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="证书名称" prop="certificateName">
              <el-input
                v-model="cerForm.certificateName"
                placeholder="请输入"
                clearable
              />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="证书编号" prop="certificateNumber">
              <el-input
                v-model="cerForm.certificateNumber"
                placeholder="请输入"
                clearable
              />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="职称" prop="jobTitle">
              <el-input
                v-model="cerForm.jobTitle"
                placeholder="请输入"
                clearable
              />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="签发日期" prop="signTime">
              <el-date-picker
                style="width: 100%"
                v-model="cerForm.signTime"
                value-format="yyyy-MM-dd"
                type="date"
                placeholder="请选择"
                clearable
              >
              </el-date-picker>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="培训开始日期" prop="cultivateCreateTime">
              <el-date-picker
                style="width: 100%"
                v-model="cerForm.cultivateCreateTime"
                value-format="yyyy-MM-dd"
                type="date"
                :picker-options="pickerOptionsF"
                placeholder="请选择"
                clearable
              >
              </el-date-picker>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="培训结束日期" prop="cultivateEndTime">
              <el-date-picker
                style="width: 100%"
                v-model="cerForm.cultivateEndTime"
                value-format="yyyy-MM-dd"
                type="date"
                :picker-options="pickerOptionsS"
                placeholder="请选择"
                clearable
              >
              </el-date-picker>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="24">
            <el-form-item label="图片上传" prop="ossId">
              <el-input v-model="cerForm.ossId" v-if="false" />
              <div class="box">
                <div class="uploadname">
                  <span>已上传图片数：{{ fileList.length }}</span>
                </div>
                <el-upload
                  ref="upload"
                  class="avatar-uploader"
                  :action="upload1.url"
                  :headers="upload1.headers"
                  list-type="picture-card"
                  :file-list="fileList"
                  :on-preview="handlePictureCardPreview"
                  :on-remove="handleRemove"
                  :on-success="handleFileSuccessSecond"
                  :before-upload="beforeAvatarUpload"
                >
                  <i class="el-icon-plus"></i>
                </el-upload>
              </div>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>

      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="handleAddCer()">确 定</el-button>
        <el-button @click="cerVisible = false">取 消</el-button>
      </div>
    </el-dialog>

    <!-- 证书列表弹框 -->
    <el-dialog
      title="查看证书"
      :visible.sync="certListVisible"
      width="1500px"
      append-to-body
      v-dialogDrag="true"
    >
      <el-form
        disabled
        ref="cerListForm"
        class="cerListForm"
        :model="cerListForm"
        size="small"
        label-width="80px"
      >
        <el-row>
          <el-col :span="4">
            <el-form-item label="姓名" prop="userName">
              <el-input v-model="cerListForm.userName" />
            </el-form-item>
          </el-col>
          <el-col :span="4">
            <el-form-item label="性别" prop="sex">
              <el-select v-model="cerListForm.sex" style="width: 100%">
                <el-option
                  v-for="dict in dict.type.sys_user_sex"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="身份证号" prop="idCard">
              <el-input v-model="cerListForm.idCard" />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <el-table :data="cerListForm.personCertificateList" ref="certable">
        <el-table-column label="序号" type="index" align="center" />
        <el-table-column
          label="证书名称"
          align="center"
          prop="certificateName"
        />
        <el-table-column
          label="证书编号"
          align="center"
          prop="certificateNumber"
        />
        <el-table-column label="职称" align="center" prop="jobTitle" />
        <el-table-column label="签发日期" align="center" prop="signTime" />
        <el-table-column label="培训开始时间" align="center">
          <template slot-scope="{ row }">
            {{ parseTime(row.cultivateCreateTime, "{y}-{m}-{d}") }}
          </template>
        </el-table-column>
        <el-table-column label="培训结束时间" align="center">
          <template slot-scope="{ row }">
            {{ parseTime(row.cultivateEndTime, "{y}-{m}-{d}") }}
          </template>
        </el-table-column>
        <el-table-column
          label="培训时长"
          align="center"
          prop="cultivateTotalTime"
        />
        <el-table-column label="证书图片" align="center" width="160">
          <template slot-scope="{ row }">
            <span v-if="row.sysOssVos && row.sysOssVos.length != 0">
              <el-image
                style="width: 100px; height: 100px"
                :src="row.sysOssVos[0].url"
                :preview-src-list="getUrl(row.sysOssVos)"
              >
                <div slot="error" class="image-slot">
                  <i class="el-icon-picture-outline"></i>
                </div>
              </el-image>
              <span style="font-weight: bolder" v-if="row.sysOssVos.length > 1">
                ...</span
              >
            </span>
          </template>
        </el-table-column>
        <el-table-column align="center" label="操作">
          <template slot-scope="{ row }">
            <el-button @click.native.prevent="openCer(row)" type="text">
              编辑
            </el-button>
            <el-button
              @click.native.prevent="deleteCer(row)"
              type="text"
              style="color: #f32d2d"
            >
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>

      <div slot="footer" class="dialog-footer">
        <el-button @click="certListVisible = false">关 闭</el-button>
      </div>
    </el-dialog>

    <!-- 添加或修改用户配置对话框 -->
    <el-dialog
      :title="title"
      :visible.sync="open"
      width="750px"
      append-to-body
      v-dialogDrag="true"
    >
      <el-form
        ref="form"
        :model="form"
        :disabled="viewStatus == '3'"
        :rules="rules"
        size="small"
        label-width="80px"
      >
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="用户昵称" prop="nickName">
              <el-input
                v-model="form.nickName"
                placeholder="请输入用户昵称"
                maxlength="30"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="归属部门" prop="deptId">
              <treeselect
                v-model="form.deptId"
                :disabled="viewStatus == '3'"
                :options="deptOptions"
                :show-count="true"
                placeholder="请选择归属部门"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="手机号码" prop="phonenumber">
              <el-input
                v-model="form.phonenumber"
                placeholder="请输入手机号码"
                maxlength="11"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="邮箱" prop="email">
              <el-input
                v-model="form.email"
                placeholder="请输入邮箱"
                maxlength="50"
              />
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="身份证号" prop="idCard">
              <el-input
                v-model="form.idCard"
                placeholder="请输入身份证号"
                maxlength="50"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item
              v-if="form.userId == undefined"
              label="用户名称"
              prop="userName"
            >
              <el-input
                v-model="form.userName"
                placeholder="请输入用户名称"
                maxlength="30"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item
              v-if="form.userId == undefined"
              label="用户密码"
              prop="password"
            >
              <el-input
                v-model="form.password"
                placeholder="请输入用户密码"
                type="password"
                maxlength="20"
                show-password
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="用户性别">
              <el-select
                v-model="form.sex"
                placeholder="请选择性别"
                style="width: 100%"
              >
                <el-option
                  v-for="dict in dict.type.sys_user_sex"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="状态">
              <el-radio-group v-model="form.status">
                <el-radio
                  v-for="dict in dict.type.sys_normal_disable"
                  :key="dict.value"
                  :label="dict.value"
                  >{{ dict.label }}</el-radio
                >
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="职务">
              <el-input
                v-model="form.duties"
                placeholder="请输入职务"
                clearable
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="角色">
              <el-select
                v-model="form.roleIds"
                multiple
                placeholder="请选择角色"
                style="width: 100%"
              >
                <el-option
                  v-for="item in roleOptions"
                  :key="item.roleId"
                  :label="item.roleName"
                  :value="item.roleId"
                  :disabled="item.status == 1"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item label="备注">
              <el-input
                v-model="form.remark"
                type="textarea"
                rows="3"
                maxlength="50"
                show-word-limit
                placeholder="请输入内容"
                clearable
              ></el-input>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" v-if="viewStatus != '3'" @click="submitForm"
          >确 定</el-button
        >
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>

    <!-- 用户导入对话框 -->
    <el-dialog
      :title="upload.title"
      :visible.sync="upload.open"
      width="400px"
      append-to-body
      v-dialogDrag="true"
    >
      <el-upload
        ref="upload"
        :limit="1"
        accept=".xlsx, .xls"
        :headers="upload.headers"
        :action="upload.url"
        :disabled="upload.isUploading"
        :on-progress="handleFileUploadProgress"
        :on-success="handleFileSuccess"
        :auto-upload="false"
        drag
      >
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
        <div class="el-upload__tip text-center" slot="tip">
          <span>仅允许导入xls、xlsx格式文件。</span>
          <el-link
            type="primary"
            :underline="false"
            style="font-size: 12px; vertical-align: baseline"
            @click="importTemplate"
            >下载模板</el-link
          >
        </div>
      </el-upload>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitFileForm">确 定</el-button>
        <el-button @click="upload.open = false">取 消</el-button>
      </div>
    </el-dialog>

    <!-- 手写弹框 -->
    <el-dialog
      title="手写签名"
      class="config-dialog"
      :visible.sync="signVisible"
      :close-on-click-modal="false"
      v-dialogDrag="true"
      append-to-body
      width="900px"
      @close="closehands"
    >
      <div class="showcode">
        <span class="title">扫码签名</span>
        <div ref="qrCodeDiv" class="qrCodeDiv"></div>
        <div class="trangle"></div>
      </div>

      <div class="content">
        <div v-if="signVisible" id="signSure" class="signSure">
          <canvas
            class="whiteBord"
            id="whiteBord"
            :style="imageUrlT && 'visibility: hidden'"
          >
          </canvas>
          <img
            v-if="imageUrlT"
            :src="imageUrlT"
            alt=""
            :draggable="false"
            class="whiteBord img"
          />
          <div class="btnBox">
            <div class="colorBox">
              <div
                class="color"
                v-for="(item, index) in colorList"
                :key="index"
                @click="changeColor(index)"
                :class="selected == index && 'selected'"
                :style="`background: ${item}`"
              ></div>
            </div>
            <font-size className="pc" @change="handleChangeSlider" />
            <button class="primaryBtn" id="againWrite">重写</button>
            <button class="primaryBtn activeBtn" id="sureWrite">确定</button>
          </div>
        </div>
      </div>
    </el-dialog>

    <div class="cusviewimgdialog" v-if="visibleImg">
      <img width="30%" :src="dialogImageUrl" alt="" />
      <span
        @click="visibleImg = false"
        class="el-image-viewer__btn el-image-viewer__close"
      >
        <i class="el-icon-close"></i>
      </span>
    </div>

    <!-- 绑定ukey -->
    <bind-user ref="bindUserRefs" />
  </div>
</template>

<script>
import {
  listUser,
  getUser,
  delUser,
  addUser,
  updateUser,
  resetUserPwd,
  changeUserStatus,
  deptTreeSelect,
  postOptionselect,
  generatorByUserId,
} from "@/api/system/user";
import {
  listPersonCertificate,
  getPersonCertificate,
  addPersonCertificate,
  updatePersonCertificate,
  delPersonCertificate,
} from "@/api/person/personCertificate";
import { listOss, listByIds, delOss } from "@/api/system/oss";
import {
  upload,
  handwritingByUserId,
  confirmSealByUserId,
} from "@/api/basicData/seal";
import { getToken } from "@/utils/auth";
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import { signature, changeOri } from "./signature";
import QRCode from "qrcodejs2";
import FontSize from "./components/fontSize";

import BindUser from "../ukey/components/bindUser.vue";

export default {
  name: "User",
  dicts: ["sys_normal_disable", "sys_user_sex"],
  components: { Treeselect, BindUser, FontSize },
  data() {
    return {
      // 遮罩层
      loading: true,
      // 选中数组
      ids: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 用户表格数据
      userList: null,
      // 弹出层标题
      title: "",
      // 部门树选项
      deptOptions: [],
      // 是否显示弹出层
      open: false,
      openPerson: false,
      // 部门名称
      deptName: undefined,
      // 默认密码
      initPassword: undefined,
      // 日期范围
      dateRange: [],
      // 岗位选项
      postOptions: [],
      // 角色选项
      roleOptions: [],
      // 证书信息
      personCertificateList: [],
      // 表单参数
      form: {},
      defaultProps: {
        children: "children",
        label: "label",
      },
      // 用户导入参数
      upload: {
        // 是否显示弹出层（用户导入）
        open: false,
        // 弹出层标题（用户导入）
        title: "",
        // 是否禁用上传
        isUploading: false,
        // 是否更新已经存在的用户数据
        updateSupport: 0,
        // 设置上传的请求头部
        headers: { Authorization: "Bearer " + getToken() },
        // 上传的地址
        url: process.env.VUE_APP_BASE_API + "/system/user/importData",
      },
      // 用户导入参数
      upload1: {
        // 是否显示弹出层（用户导入）
        open: false,
        // 弹出层标题（用户导入）
        title: "",
        // 是否禁用上传
        isUploading: false,
        // 是否更新已经存在的用户数据
        updateSupport: 0,
        // 设置上传的请求头部
        headers: {
          Authorization: "Bearer " + getToken(),
          "Content-Disposition": "inline",
        },
        // 上传的地址
        url: process.env.VUE_APP_BASE_API + "/system/oss/upload",
      },
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        userName: undefined,
        phonenumber: undefined,
        status: undefined,
        deptId: undefined,
      },
      // 列信息
      columns: [
        { key: 0, label: `用户编号`, visible: true },
        { key: 1, label: `用户名称`, visible: true },
        { key: 2, label: `用户昵称`, visible: true },
        { key: 3, label: `部门`, visible: true },
        { key: 4, label: `手机号码`, visible: true },
        { key: 5, label: `状态`, visible: true },
        { key: 6, label: `创建时间`, visible: true },
      ],
      // 表单校验
      rules: {
        userName: [
          { required: true, message: "用户名称不能为空", trigger: "blur" },
          {
            min: 2,
            max: 20,
            message: "用户名称长度必须介于 2 和 20 之间",
            trigger: "blur",
          },
        ],
        nickName: [
          { required: true, message: "用户昵称不能为空", trigger: "blur" },
        ],
        password: [
          { required: true, message: "用户密码不能为空", trigger: "blur" },
          {
            min: 5,
            max: 20,
            message: "用户密码长度必须介于 5 和 20 之间",
            trigger: "blur",
          },
        ],
        email: [
          {
            type: "email",
            message: "请输入正确的邮箱地址",
            trigger: ["blur", "change"],
          },
        ],
        idCard: [
          {
            pattern: /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/,
            message: "请输入正确的身份证号",
            trigger: "blur",
          },
        ],
        phonenumber: [
          {
            pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
            message: "请输入正确的手机号码",
            trigger: "blur",
          },
        ],
      },
      // 视图高度
      height: document.documentElement.clientHeight,
      // 证书表单
      cerListForm: {},
      certificateTitle: "",
      // 证书列表显示
      certListVisible: false,
      // 弹框禁用
      certificateDisabled: true,
      // 证书显示
      cerVisible: false,
      // 添加证书表单
      cerForm: {},
      // 添加证书表单校验
      addCerRules: {
        certificateName: [
          { required: true, message: "证书名称不能为空", trigger: "blur" },
        ],
        certificateNumber: [
          { required: true, message: "证书编号不能为空", trigger: "blur" },
        ],
      },
      // 打开的userId
      userId: null,
      //
      certificateIds: [],
      // 证书弹框状态
      status: false,
      // 查看弹框状态
      viewStatus: null,
      selection: [],
      visibleImg: false,
      dialogImageUrl: "",
      fileList: [],
      // 预览图片查询的url列表
      dialogImageUrlList: [],
      // 职务下拉框
      postSelect: [],
      // 日期校验
      pickerOptionsF: {
        disabledDate: (time) => {
          return (
            time.getTime() > new Date(this.cerForm.cultivateEndTime).getTime()
          );
        },
      },
      pickerOptionsS: {
        disabledDate: (time) => {
          return (
            time.getTime() <
            new Date(this.cerForm.cultivateCreateTime).getTime()
          );
        },
      },
      signVisible: false,
      ws: null,
      imageUrlT: null,
      colorList: ["#000", "red", "blue"] /* 颜色列表 */,
      selected: 0 /* 选中的颜色 */,
    };
  },
  watch: {
    // 根据名称筛选部门树
    deptName(val) {
      this.$refs.tree.filter(val);
    },
  },
  created() {
    this.getList();
    this.getDeptTree();
    // this.getPostOptionselect();
    this.getConfigKey("sys.user.initPassword").then((response) => {
      this.initPassword = response.msg;
    });
  },
  computed: {
    getUrl() {
      return (value) => {
        let list = [];
        list = value.map((item) => {
          return item.url;
        });
        return list;
      };
    },
  },
  methods: {
    /** 查询用户列表 */
    getList() {
      this.loading = true;
      listUser(this.addDateRange(this.queryParams, this.dateRange)).then(
        (response) => {
          this.userList = response.rows;
          this.userList.forEach((item) => {
            if (item.sealOssId) {
              listByIds(item.sealOssId).then((response) => {
                this.$set(
                  item,
                  "sealurl",
                  response.data[0] && response.data[0].url
                );
              });
            }
          });
          this.total = response.total;
          this.loading = false;
        }
      );
    },
    // 更多操作触发
    handleCommand(command, row) {
      switch (command) {
        case "handleSysSeal" /* 系统生成签章 */:
          this.handleGenerate(row);
          break;
        case "handleHanSeal" /* 手写签章 */:
          this.showSign(row);
          break;
        default:
          break;
      }
    },
    // 打开绑定ukey弹窗
    openUkeyDialog() {
      let select = this.selection[0];
      this.$refs["bindUserRefs"].openDialog({
        userId: select.userId,
      });
    },
    // 系统生成签章
    handleGenerate(row) {
      generatorByUserId(row.userId).then((response) => {
        this.$modal.msgSuccess("生成成功");
        this.getList();
      });
    },
    // 打开手写签名
    showSign(row) {
      this.signVisible = true;
      this.imageUrlT = null;
      this.$nextTick(() => {
        let params = {
          whiteBord: "whiteBord", //canvas标签的id名称
          againWrite: "againWrite", //重写按钮id名
          sureWrite: "sureWrite", //确认按钮id名
          maxFonts: 20,
          minFonts: 16,
          clearWriteCallback: () => {
            //重写的回调函数
            this.imageUrlT = null;
          },
          sureWriteCallback: (imageBase64) => {
            //签名完成后的回调函数
            this.suresign(imageBase64, row);
          },
        };
        signature(params);
        let VUE_APP_CONTEXT_PATH =
          process.env.VUE_APP_CONTEXT_PATH == "/"
            ? ""
            : process.env.VUE_APP_CONTEXT_PATH;
        let url =
          "http://" +
          document.location.host +
          VUE_APP_CONTEXT_PATH +
          "/handsf?userId=" +
          row.userId;
        console.log("url", url);
        this.qrcode = new QRCode(this.$refs.qrCodeDiv, {
          text: url,
          width: 100,
          height: 100,
          colorDark: "#333333", //二维码颜色
          colorLight: "#ffffff", //二维码背景色
          correctLevel: QRCode.CorrectLevel.L, //容错率，L/M/H
        });
        let prefixUrl = `ws://${document.location.host}${process.env.VUE_APP_BASE_API}/ws/signature/`;
        //创建WebSocket连接对象
        this.ws = new WebSocket(prefixUrl + row.userId);
        //连接成功建立
        this.ws.onopen = function (event) {
          console.log("建立连接", event);
        };
        //接收到消息
        this.ws.onmessage = (event) => {
          console.log("接收到内容：" + event.data);
          if (event.data) {
            this.$set(this, "imageUrlT", "data:image/png;base64," + event.data);
          }
        };
        //连接发生错误
        this.ws.onerror = function (event) {
          console.log("发生错误");
        };
        //连接关闭
        this.ws.onclose = function (event) {
          console.log("关闭连接");
        };
      });
    },
    handleChangeSlider(val) {
      changeOri("changeSize", null, {
        maxFonts: val,
        minFonts: val - 4,
      });
    },
    // 签名完成
    suresign(imageBase64, row) {
      console.log("imageBase64", imageBase64);
      let base64;
      if (this.imageUrlT) {
        /* 上传的图片 */
        base64 = this.imageUrlT;
      } else if (imageBase64 != "empty") {
        /* 绘制的图片 */
        base64 = imageBase64;
      } else {
        this.$modal.msgWarning("签名不能为空");
        return;
      }

      let blob = this.dataURLtoBlob(base64);
      let file1 = this.blobToFile(blob, "handsfile");
      let fd = new FormData();
      fd.append("file", file1);
      upload(fd).then((response) => {
        console.log("uploadResponse", response);
        confirmSealByUserId(row.userId, response.data.ossId).then(
          (response) => {
            this.$modal.msgSuccess("签名成功");
            this.getList();
            this.signVisible = false;
            this.ws.close();
          }
        );
      });
    },
    // 将base64转换为blob
    dataURLtoBlob(dataurl) {
      var arr = dataurl.split(","),
        mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]),
        n = bstr.length,
        u8arr = new Uint8Array(n);
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
      }
      return new Blob([u8arr], { type: mime });
    },
    // 将blob转换为file
    blobToFile(theBlob, fileName) {
      theBlob.lastModifiedDate = new Date(); // 文件最后的修改日期
      theBlob.name = fileName; // 文件名
      return new File([theBlob], fileName, {
        type: theBlob.type,
        lastModified: Date.now(),
      });
    },
    // 更改颜色
    changeColor(index) {
      this.selected = index;
      changeOri("changeColor", this.colorList[index]);
    },
    // 关闭手写弹框
    closehands() {
      console.log("closehands");
      let qrCodeDiv = document.getElementsByClassName("qrCodeDiv");
      qrCodeDiv[0].innerHTML = "";
      this.ws.close();
    },
    /** 查询部门下拉树结构 */
    getDeptTree() {
      deptTreeSelect().then((response) => {
        this.deptOptions = response.data;
      });
    },
    // 筛选节点
    filterNode(value, data) {
      if (!value) return true;
      return data.label.indexOf(value) !== -1;
    },
    // 节点单击事件
    handleNodeClick(data) {
      this.queryParams.deptId = data.id;
      this.handleQuery();
    },
    // 用户状态修改
    handleStatusChange(row) {
      let text = row.status === "0" ? "启用" : "停用";
      this.$modal
        .confirm('确认要"' + text + '""' + row.userName + '"用户吗？')
        .then(function () {
          return changeUserStatus(row.userId, row.status);
        })
        .then(() => {
          this.$modal.msgSuccess(text + "成功");
        })
        .catch(function () {
          row.status = row.status === "0" ? "1" : "0";
        });
    },
    // 取消按钮
    cancel() {
      this.open = false;
      this.reset();
    },
    // 表单重置
    reset() {
      this.form = {
        userId: undefined,
        deptId: undefined,
        userName: undefined,
        nickName: undefined,
        password: undefined,
        phonenumber: undefined,
        email: undefined,
        sex: undefined,
        idCard: undefined,
        status: "0",
        personCertificateList: [],
        postIds: [],
        roleIds: [],
      };
      this.resetForm("form");
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getList();
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.dateRange = [];
      this.resetForm("queryForm");
      this.queryParams.deptId = undefined;
      // this.$refs.tree.setCurrentKey(null);
      this.handleQuery();
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.selection = selection;
      console.log("this.selection", this.selection);
      this.ids = selection.map((item) => item.userId);
      this.single = selection.length != 1;
      this.multiple = !selection.length;
    },
    /** 新增按钮操作 */
    handleAdd() {
      this.reset();
      getUser().then((response) => {
        this.postOptions = response.data.posts;
        this.roleOptions = response.data.roles;
        this.open = true;
        this.title = "添加用户";
        this.form.password = this.initPassword;
      });
    },
    // 打开证书
    openCer(row) {
      this.resetForm("cerForm");
      this.fileList = [];
      if (row) {
        this.cerForm = {
          userName: this.cerListForm.userName,
          idCard: this.cerListForm.idCard,
          sex: this.cerListForm.sex,
          personnelId: this.cerListForm.personnelId,
          ...row,
        };
        if (row.sysOssVos) {
          this.fileList = row.sysOssVos.map((item) => {
            return {
              name: item.originalName,
              url: item.url,
              ossId: item.ossId,
            };
          });
          console.log("this.fileList", this.fileList);
        }
        console.log("修改证书", this.cerForm);
        this.status = "2";
      } else {
        this.cerForm = {
          // ...row,
          userName: this.selection[0].userName,
          idCard: this.selection[0].idCard,
          sex: this.selection[0].sex,
          personnelId: this.selection[0].userId,
        };
        console.log("添加证书", this.cerForm);
        this.status = "1";
      }
      this.cerVisible = true;
    },
    // 打开证书列表
    openCerList(row) {
      this.resetCerListForm();
      this.cerListForm = {
        userName: row.userName,
        idCard: row.idCard,
        sex: row.sex,
        personnelId: row.userId,
        personCertificateList: [],
      };
      console.log("打开证书列表", this.cerListForm);
      listPersonCertificate({ personnelId: row.userId }).then((response) => {
        this.cerListForm.personCertificateList = response.data;
      });
      this.userId = row.userId;
      this.certListVisible = true;
    },
    // 重置证书列表
    resetCerListForm() {
      this.cerListForm = {
        userName: "",
        idCard: "",
        sex: "",
        personCertificateList: [],
      };
      this.resetForm("cerListForm");
    },
    // 预览图片
    viewImg(ossId) {
      listByIds(ossId).then((response) => {
        this.dialogImageUrlList = response.data.map((item) => item.url);
        this.visibleImg = true;
      });
    },
    // 提交证书
    handleAddCer() {
      this.$refs["cerForm"].validate((valid) => {
        if (valid) {
          // this.cerForm.personnelId = this.userId;
          this.cerForm.certificateOssId = this.fileList
            .map((item) => {
              if (item.ossId) {
                return item.ossId; /* 回显的列表格式 */
              } else if (item.response.data) {
                return item.response.data.ossId; /* 新上传的列表格式 */
              }
            })
            .join(",");
          if (this.status == "1") {
            addPersonCertificate(this.cerForm).then((response) => {
              this.$modal.msgSuccess("上传成功");
              this.cerVisible = false;
              this.getList();
            });
          } else {
            updatePersonCertificate(this.cerForm).then((response) => {
              this.$modal.msgSuccess("修改成功");
              this.cerVisible = false;
              this.getList();
              // 刷新证书列表
              listPersonCertificate({
                personnelId: this.cerForm.personnelId,
              }).then((response) => {
                this.cerListForm.personCertificateList = response.data;
              });
            });
          }
        }
      });
    },
    // 删除证书
    deleteCer(row) {
      this.$modal
        .confirm("是否确认删除该证书？")
        .then(function () {
          return delPersonCertificate(row.certificateId);
        })
        .then(() => {
          this.$modal.msgSuccess("删除成功");
          this.getList();
          // 刷新证书列表
          listPersonCertificate({ personnelId: this.cerForm.personnelId }).then(
            (response) => {
              this.cerListForm.personCertificateList = response.data;
            }
          );
        })
        .catch(() => {});
    },
    /** 修改按钮操作 */
    handleUpdate(row, viewStatus) {
      this.reset();
      const userId = row.userId || this.ids;
      getUser(userId).then((response) => {
        this.form = response.data.user;
        this.postOptions = response.data.posts;
        this.roleOptions = response.data.roles;
        this.$set(this.form, "postIds", response.data.postIds);
        this.$set(this.form, "roleIds", response.data.roleIds);
        this.open = true;
        this.viewStatus = viewStatus;
        if (this.viewStatus == "3") {
          this.title = "查看用户";
        } else {
          this.title = "修改用户";
        }
        this.form.password = "";
      });
    },
    /** 重置密码按钮操作 */
    handleResetPwd(row) {
      this.$modal.confirm(`是否确认重置密码？`).then(() => {
        resetUserPwd(row.userId, "").then((response) => {
          this.$modal.msgSuccess("重置成功");
        });
      });
    },
    /** 提交按钮 */
    submitForm: function () {
      this.$refs["form"].validate((valid) => {
        if (valid) {
          if (this.form.userId != undefined) {
            updateUser(this.form).then((response) => {
              this.$modal.msgSuccess("修改成功");
              this.open = false;
              this.getList();
            });
          } else {
            addUser(this.form).then((response) => {
              this.$modal.msgSuccess("新增成功");
              this.open = false;
              this.getList();
            });
          }
        }
      });
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      const userIds = row.userId || this.ids;
      this.$modal
        .confirm(`是否确认删除用户 [${row.userName}]？`)
        .then(function () {
          return delUser(userIds);
        })
        .then(() => {
          this.getList();
          this.$modal.msgSuccess("删除成功");
        })
        .catch(() => {});
    },
    /** 导出按钮操作 */
    handleExport() {
      this.download(
        "system/user/export",
        {
          ...this.queryParams,
        },
        `user_${new Date().getTime()}.xlsx`
      );
    },
    /** 导入按钮操作 */
    handleImport() {
      this.upload.title = "用户导入";
      this.upload.open = true;
    },
    /** 下载模板操作 */
    importTemplate() {
      this.download(
        "system/user/importTemplate",
        {},
        `user_template_${new Date().getTime()}.xlsx`
      );
    },
    // 文件上传中处理
    handleFileUploadProgress(event, file, fileList) {
      this.upload.isUploading = true;
    },
    // 文件上传成功处理
    handleFileSuccess(response, file, fileList) {
      this.upload.open = false;
      this.upload.isUploading = false;
      this.$refs.upload.clearFiles();
      this.$alert(
        "<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
          response.msg +
          "</div>",
        "导入结果",
        { dangerouslyUseHTMLString: true }
      );
      this.getList();
    },
    // 提交上传文件
    submitFileForm() {
      this.$refs.upload.submit();
    },
    // 文件上传成功处理
    handleFileSuccessSecond(response, file, fileList) {
      console.log("response, file, fileList", response, file, fileList);
      if (response.code == 500) {
        this.$modal.msgWarning(response.msg);
      }
      this.fileList = fileList;
      this.cerForm.certificateOssId = response.data && response.data.ossId;
      this.upload.open = false;
      this.upload.isUploading = false;
    },
    // 文件移除
    handleRemove(file, fileList) {
      this.fileList = fileList;
    },
    // 上传时的预览图片
    handlePictureCardPreview(file) {
      this.dialogImageUrl = file.url;
      this.visibleImg = true;
    },
    // 上传前
    beforeAvatarUpload(file) {
      let myisJPG = file.type === "image/jpeg" || file.type === "image/png";
      if (!myisJPG) {
        this.$message.error("请上传图片格式!");
      }
      return myisJPG;
    },
  },
};
</script>
<style lang="scss" scoped>
.mybutton {
  padding: 5px 10px !important;
}
.imgView {
  color: #2a72ee;
  cursor: pointer;
  margin-right: 10px;
  &:hover {
    text-decoration: underline;
  }
}
.imgcontainer {
  display: flex;
  justify-content: space-evenly;
  align-items: center;
  flex-wrap: wrap;
  img {
    width: 45%;
  }
}
::v-deep .vue-treeselect__control {
  height: 30px;
  border-radius: 4px;
}
::v-deep .pagination-container {
  margin-top: 34px;
}
.searchform {
  margin-left: -34px;
}
.certificate {
  margin: 0 0 0 auto;
}
::v-deep .el-textarea__inner {
  resize: none;
}
.cerForm {
  margin-left: -20px;
}
.cerListForm {
  margin-left: -25px;
}
.seal {
  display: flex;
  justify-content: center;
  align-items: center;
  img {
    // max-width: 100%;
    max-height: 35px;
  }
}
.config-dialog {
  ::v-deep .el-dialog__body {
    padding: 0;
  }
}
.showcode {
  position: absolute;
  top: 7px;
  right: 118px;
  font-size: 16px;
  font-weight: bold;
  text-align: center;
  width: 108px;
  z-index: 1;
  cursor: pointer;
  .title {
    line-height: 50px;
    color: #3c3c3c;
  }
  &:hover {
    .qrCodeDiv {
      display: block;
    }
    .trangle {
      display: block;
    }
  }
  .qrCodeDiv {
    border: 1px solid #999;
    padding: 3px;
    // height: 0;
    display: none;
    transition: all 0.3s;
    margin-top: -3px;
  }
  .trangle {
    border-top: 7px solid transparent;
    border-right: 7px solid transparent;
    border-bottom: 7px solid #434343;
    border-left: 7px solid transparent;
    position: absolute;
    top: 33px;
    right: 48px;
    display: none;
  }
}
.content {
  height: 383px;
}
.signSure {
  border-radius: 16px;
  position: relative;
  .topTitle {
    margin: 20px 0 12px 12px;
    font-size: 16px;
  }
  .whiteBord {
    width: 100%;
    height: 300px;
    border-bottom: 1px solid #eee;
    margin: 0 auto;
    border-radius: 4px;
    cursor: pointer;
    &.img {
      position: absolute;
      top: 0;
      right: 0;
      cursor: not-allowed;
    }
  }
  .btnBox {
    padding: 20px 50px;
    display: flex;
    justify-content: space-between;
    .colorBox {
      display: flex;
      align-items: center;
      justify-content: center;
      margin-right: 20px;
      .color {
        width: 18px;
        height: 18px;
        border-radius: 50%;
        margin-right: 10px;
        &:hover {
          cursor: pointer;
        }
      }
      .selected {
        transform: scale(1.3);
      }
    }
    .primaryBtn {
      width: 40%;
      height: 40px;
      color: #666;
      border: 1px solid #ccc;
      border-radius: 4px;
      background: #fff;
      cursor: pointer;
      transition: 0.4s cubic-bezier(0.175, 0.885, 0.32, 1);
      transition-property: background, border, box-shadow, outline, opacity;
      &:hover {
        background-color: #dedede;
        border-color: #a1a1a1;
        box-shadow: 0 2px 1px rgba(0, 0, 0, 0.1);
      }
      &:nth-of-type(1) {
        margin-right: 30px;
      }
    }
    .activeBtn {
      background: #2a72ee;
      color: #fff;
      border: none;
      &:hover {
        background-color: #46a6ff;
      }
    }
  }
}
.mb8{
  margin-bottom: 0px;
}
</style>
